#!/usr/bin/python
"""
testing.py
"""

__all__ = ['testall']

import cre_compile


def TestMethod(t, cre, method, case_list):
  """
  Args:
    method: callable
    case_list: list of tuples
  """
  for case in case_list:
    if isinstance(case, basestring):
      in_ = case
      expected0 = None
      do_test = False

    else:  # tuple
      if len(case) == 2:
        in_, expected0 = case
        do_test = True
      else:
        raise AssertionError('Invalid case %r' % case)

    # TODO: Better errors for these 3 cases.
    m = method(in_)
    if not m:
      t.fail('Expected %r to match %r' % (cre, in_))

    # Don't test if it's None.
    if do_test:
      t.assertEqual(expected0, m)


def testall(test_case, expect_list):
  """
  Args:
    test_case: unittest.TestCase instance
    expect_list: List of dictionary test cases.

  Returns:
    None

  Calls test_case.fail()
  """
  t = test_case  # shortcut

  for e in expect_list:
    name = e.get('name')
    cre = e.get('cre')

    r = cre_compile.Regex(cre)

    TestMethod(t, cre, r.match, e.get('match') or [])
    TestMethod(t, cre, r.matchspan, e.get('matchspan') or [])
    TestMethod(t, cre, r.capture, e.get('capture') or [])
    TestMethod(t, cre, r.capturespans, e.get('capturespans') or [])

    nomatch_list = e.get('nomatch') or []
    for case in nomatch_list:
      m = r.match(case)
      if m is not None:
        t.fail("Expected %r not to match %r, but it did" % (case, cre))
